// =====================================================================
//
//  This file is part of the Microsoft Dynamics CRM SDK code samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//
// =====================================================================
namespace Microsoft.Xrm.Sdk.Query
{
    using System.Runtime.Serialization;

	[DataContract(Name = "QueryExpression", Namespace = XmlNamespaces.V5.Contracts)]
	public sealed class QueryExpression : QueryBase
	{
		public QueryExpression()
			: this(null)
		{
		}

		public QueryExpression(string entityName)
		{
			_entityName = entityName;
			_criteria = new FilterExpression();
			_pageInfo = new PagingInfo();
			_columnSet = new ColumnSet();
		}

		[DataMember]
		public bool Distinct
		{
			get
			{
				return _distinct;
			}
			set
			{
				_distinct = value;
			}
		}

		[DataMember(Order = 50)]
		public bool NoLock
		{
			get
			{
				return _noLock;
			}
			set
			{
				_noLock = value;
			}
		}

		[DataMember]
		public PagingInfo PageInfo
		{
			get
			{
				return _pageInfo;
			}
			set
			{
				_pageInfo = value;
			}
		}

		[DataMember]
		public DataCollection<LinkEntity> LinkEntities
		{
			get
			{
				if (_linkEntities == null)
				{
					_linkEntities = new DataCollection<LinkEntity>();
				}
				return _linkEntities;
			}
			private set
			{
				_linkEntities = value;
			}
		}

		[DataMember]
		public FilterExpression Criteria
		{
			get
			{
				return _criteria;
			}
			set
			{
				_criteria = value;
			}
		}

		[DataMember]
		public DataCollection<OrderExpression> Orders
		{
			get
			{
				if (_orders == null)
				{
					_orders = new DataCollection<OrderExpression>();
				}
				return _orders;
			}
			private set
			{
				_orders = value;
			}
		}

		[DataMember]
		public string EntityName
		{
			get
			{
				return _entityName;
			}
			set
			{
				_entityName = value;
			}
		}

		[DataMember]
		public ColumnSet ColumnSet
		{
			get
			{
				return _columnSet;
			}
			set
			{
				_columnSet = value;
			}
		}

		[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
		internal override void Accept(IQueryVisitor visitor)
		{
			visitor.Visit(this);
		}

		public void AddOrder(string attributeName, OrderType orderType)
		{
			this.Orders.Add(new OrderExpression(attributeName, orderType));
		}

		public LinkEntity AddLink(string linkToEntityName, string linkFromAttributeName, string linkToAttributeName)
		{
			return AddLink(linkToEntityName, linkFromAttributeName, linkToAttributeName, JoinOperator.Inner);
		}

		public LinkEntity AddLink(string linkToEntityName, string linkFromAttributeName, string linkToAttributeName, JoinOperator joinOperator)
		{
			LinkEntity link = new LinkEntity(
				EntityName,
				linkToEntityName,
				linkFromAttributeName,
				linkToAttributeName,
				joinOperator);

			this.LinkEntities.Add(link);

			return link;
		}

		private ColumnSet _columnSet;
		private string _entityName;
		private bool _distinct;
		private bool _noLock;
		private PagingInfo _pageInfo;
		private DataCollection<LinkEntity> _linkEntities;
		private FilterExpression _criteria;
		private DataCollection<OrderExpression> _orders;
	}
}

